import sys
from pathlib import Path
import json
from typing import Optional, Tuple, Dict, Any, Union

try:
    # 先尝试直接导入
    from auth_sms_code_api import AuthSmsCodeApi
    from auth_sms_login_api import AuthSmsLoginApi
    from auth_sms_up_config_api import AuthSmsUpConfigApi
    from auth_sms_up_login_api import AuthSmsUpLoginApi
    from app_count_api import AppCountApi
    from device_info_api import DeviceInfoApi, DeviceInfoRequest
    from model.sms_code_models import SendSignInSmsCodeResponse
    from model.sms_login_models import SmsSignInResponse
    from model.sms_up_config_models import SmsUpConfigResponse
    from model.sms_up_login_models import SmsUpSignInResponse
except ImportError:
    # 如果直接导入失败，尝试使用相对导入
    from .auth_sms_code_api import AuthSmsCodeApi
    from .auth_sms_login_api import AuthSmsLoginApi
    from .auth_sms_up_config_api import AuthSmsUpConfigApi
    from .auth_sms_up_login_api import AuthSmsUpLoginApi
    from .app_count_api import AppCountApi
    from .device_info_api import DeviceInfoApi, DeviceInfoRequest
    from .model.sms_code_models import SendSignInSmsCodeResponse
    from .model.sms_login_models import SmsSignInResponse
    from .model.sms_up_config_models import SmsUpConfigResponse
    from .model.sms_up_login_models import SmsUpSignInResponse


class AuthIntegratedLogin:
    """登录整合类，提供多种登录方式"""
    
    def __init__(self, device_id: str = None, uk: str = None):
        """初始化登录整合类
        
        Args:
            device_id: 设备ID，如果不传则自动生成
            uk: UK值，如果不传则使用空字符串
        """
        self.device_id = device_id or ""
        self.uk = uk or ""
        

    
    def send_sms_code(self, mobile: str, area: str = "86") -> Union[str, Tuple[str, str]]:
        """发送短信验证码
        
        Args:
            mobile: 手机号码
            area: 区号，默认为中国区号86
            
        Returns:
            Union[str, Tuple[str, str]]: 
                如果发送成功，返回成功提示信息
                如果需要上行短信，返回(上行短信内容, 上行短信号码)元组
        """
        # 创建短信验证码API实例
        sms_code_api = AuthSmsCodeApi(
            device_token=self.device_id,
            device_id=self.device_id,
            auth_token="Bearer",
            uk=self.uk
        )
        
        # 发送短信验证码
        response = sms_code_api.send_sign_in_sms_code(
            mobile=mobile,
            code="",
            area=area
        )
        
        # 检查响应状态码
        if response.Code == 0:
            # 发送成功
            return f"验证码发送成功，有效期{response.Data.Secs}秒"
        elif response.Code == 5050:
            # 需要使用上行短信方式
            print(f"普通短信验证码发送失败: {response.Msg}")
            print("尝试获取短信上行配置...")
            
            # 创建短信上行配置API实例
            sms_up_config_api = AuthSmsUpConfigApi(
                device_token=self.device_id,
                device_id=self.device_id,
                auth_token="Bearer",
                uk=self.uk
            )
            
            # 获取短信上行配置
            config_response = sms_up_config_api.get_sms_up_sign_in_config()
            
            # 检查响应状态码
            if config_response.Code == 0 and config_response.Data:
                # 返回上行短信内容和号码
                return (
                    config_response.Data.SmsUpContent,
                    config_response.Data.SmsUpNumber
                )
            else:
                # 获取上行配置失败
                raise Exception(f"获取短信上行配置失败: {config_response.Msg}")
        else:
            # 其他错误
            raise Exception(f"发送短信验证码失败: {response.Msg}")
    
    def _report_app_count(self, token: str) -> bool:
        """上报应用计数
        
        Args:
            token: 登录令牌
            
        Returns:
            bool: 是否上报成功
        """
        try:
            # 创建应用计数上报API实例
            app_count_api = AppCountApi(
                device_token=self.device_id,
                device_id=self.device_id,
                auth_token="",
                uk=self.uk
            )
            
            # 发送应用计数上报请求
            response = app_count_api.add_app_up_count(token)
            
            # 检查响应状态码
            if response.code == 0:
                print("应用计数上报成功")
                return True
            else:
                print(f"应用计数上报失败: {response.msg}")
                return False
        except Exception as e:
            print(f"应用计数上报异常: {e}")
            return False
    
    def _report_device_info(self, token: str = "", user_id: int = 0) -> str:
        """上报设备信息
        
        Args:
            token: 登录令牌，如果有的话
            user_id: 用户ID，如果有的话
            
        Returns:
            str: 成功返回新的UK值，失败返回空字符串
        """
        try:
            # 创建设备信息API实例
            device_info_api = DeviceInfoApi(
                device_token=self.device_id,
                device_id=self.device_id,
                auth_token=token,
                uk=self.uk
            )
            
            # 创建设备信息请求对象
            request = DeviceInfoRequest.create_default(
                device_id=self.device_id,
                uk=self.uk,
                user_id=user_id
            )
            
            # 发送设备信息上报请求
            response = device_info_api.report_device_info(request)
            
            # 检查响应状态码
            if response.code == 0 and response.data and 'uk' in response.data:
                new_uk = response.data['uk']
                print(f"设备信息上报成功，获取新的UK值: {new_uk}")
                # 更新实例中的UK值
                self.uk = new_uk
                return new_uk
            else:
                print(f"设备信息上报失败: {response.msg}")
                return ""
        except Exception as e:
            print(f"设备信息上报异常: {e}")
            return ""
    
    def login_with_sms_code(self, mobile: str, code: str, area: str = "86") -> Dict[str, Any]:
        """使用短信验证码登录
        
        Args:
            mobile: 手机号码
            code: 短信验证码
            area: 区号，默认为中国区号86
            
        Returns:
            Dict[str, Any]: 登录成功后的用户信息，包括token、昵称等
        """
        # 创建短信登录API实例
        sms_login_api = AuthSmsLoginApi(
            device_token=self.device_id,
            device_id=self.device_id,
            auth_token="Bearer",
            uk=self.uk
        )
        
        # 发送短信登录请求
        response = sms_login_api.sms_sign_in(
            mobile=mobile,
            code=code,
            area=area
        )
        
        # 检查响应状态码
        if response.Code == 0 and response.Data:
            # 登录成功，获取用户信息
            user_info = {
                "token": response.Data.Token,
                "nickname": response.Data.NickName,
                "is_open_stock": response.Data.IsOpenStock,
                "is_reg": response.Data.IsReg,
                "foreign_account_tips": response.Data.ForeignAccountTips
            }
            
            # 上报应用计数
            self._report_app_count(response.Data.Token)
            
            # 上报设备信息
            # 从token中提取用户ID（如果可能的话）
            user_id = 0  # 默认为0
            try:
                # JWT token通常由三部分组成，用.分隔，第二部分是payload
                token_parts = response.Data.Token.split('.')
                if len(token_parts) >= 2:
                    import base64
                    import json
                    # 解码payload部分，处理填充问题
                    payload_part = token_parts[1]
                    # 添加填充使其长度为4的倍数
                    padding_needed = len(payload_part) % 4
                    if padding_needed:
                        payload_part += '=' * (4 - padding_needed)
                    # 使用更安全的解码方式
                    try:
                        decoded = base64.urlsafe_b64decode(payload_part)
                        payload = json.loads(decoded.decode('utf-8', errors='ignore'))
                        if 'Id' in payload:
                            user_id = int(payload['Id'])
                            print(f"从token中提取用户ID: {user_id}")
                            # 将用户ID添加到用户信息中
                            user_info["user_id"] = user_id
                    except Exception as e:
                        print(f"解码token payload失败: {e}")
            except Exception as e:
                print(f"提取用户ID失败: {e}")
            
            # 上报设备信息，获取新的UK值
            new_uk = self._report_device_info(response.Data.Token, user_id)
            if new_uk:
                user_info["uk"] = new_uk
            
            return user_info
        else:
            # 登录失败
            raise Exception(f"短信登录失败: {response.Msg}")
    
    def login_with_sms_up(self, mobile: str, area: str = "86") -> Dict[str, Any]:
        """使用短信上行方式登录
        
        Args:
            mobile: 手机号码
            area: 区号，默认为中国区号86
            
        Returns:
            Dict[str, Any]: 登录成功后的用户信息，包括token、昵称等
        """
        # 创建短信上行登录API实例
        sms_up_login_api = AuthSmsUpLoginApi(
            device_token=self.device_id,
            device_id=self.device_id,
            auth_token="Bearer",
            uk=self.uk
        )
        
        # 发送短信上行登录请求
        response = sms_up_login_api.sms_up_sign_in(
            mobile=mobile,
            code="",  # 上行短信方式不需要验证码
            area=area
        )
        
        # 检查响应状态码
        if response.Code == 0 and response.Data:
            # 登录成功，获取用户信息
            user_info = {
                "token": response.Data.Token,
                "nickname": response.Data.NickName,
                "is_open_stock": response.Data.IsOpenStock,
                "is_reg": response.Data.IsReg,
                "foreign_account_tips": response.Data.ForeignAccountTips
            }
            
            # 上报应用计数
            self._report_app_count(response.Data.Token)
            
            # 上报设备信息
            # 从token中提取用户ID（如果可能的话）
            user_id = 0  # 默认为0
            try:
                # JWT token通常由三部分组成，用.分隔，第二部分是payload
                token_parts = response.Data.Token.split('.')
                if len(token_parts) >= 2:
                    import base64
                    import json
                    # 解码payload部分，处理填充问题
                    payload_part = token_parts[1]
                    # 添加填充使其长度为4的倍数
                    padding_needed = len(payload_part) % 4
                    if padding_needed:
                        payload_part += '=' * (4 - padding_needed)
                    # 使用更安全的解码方式
                    try:
                        decoded = base64.urlsafe_b64decode(payload_part)
                        payload = json.loads(decoded.decode('utf-8', errors='ignore'))
                        if 'Id' in payload:
                            user_id = int(payload['Id'])
                            print(f"从token中提取用户ID: {user_id}")
                            # 将用户ID添加到用户信息中
                            user_info["user_id"] = user_id
                    except Exception as e:
                        print(f"解码token payload失败: {e}")
            except Exception as e:
                print(f"提取用户ID失败: {e}")
            
            # 上报设备信息，获取新的UK值
            new_uk = self._report_device_info(response.Data.Token, user_id)
            if new_uk:
                user_info["uk"] = new_uk
            
            return user_info
        else:
            # 登录失败
            raise Exception(f"短信上行登录失败: {response.Msg}")


def main():
    """测试登录整合类"""
    try:
        # device_id = "Z+Z/Uj4xyKoDAJp249r21qHx"
        # uk = "5FGaLrLar6b7EWUnNmqNpKGjU88E7TrsHnqsWlwo9ncsogqazR1hLGldi30biVJ1N"
        device_id = "Z7LeH7vdDYcDAIYI3/TVXfAH"
        uk = "5FDFSRFUD0wsn4vgzgeZpQIxPQzgCtMd3SfawJ2FStxg6MCO4d1esVBdyWoCfkr1N"
        # 创建登录整合类实例
        auth = AuthIntegratedLogin(device_id, uk)
        
        # 测试手机号
        mobile = "13186793939"
        
        # 1. 发送短信验证码
        print("\n===== 测试发送短信验证码 =====")
        result = auth.send_sms_code(mobile)
        
        if isinstance(result, tuple):
            # 需要上行短信
            sms_content, sms_number = result
            print(f"请发送短信内容 '{sms_content}' 到号码 {sms_number}")
            
            # 2. 测试短信上行登录
            print("\n===== 测试短信上行登录 =====")
            print("请在发送短信后，按Enter键继续...")
            input()
            
            try:
                user_info = auth.login_with_sms_up(mobile)
                print("短信上行登录成功！")
                print(f"用户昵称: {user_info['nickname']}")
                print(f"登录令牌: {user_info['token'][:30]}...")
                if 'uk' in user_info:
                    print(f"新的UK值: {user_info['uk']}")
                if 'user_id' in user_info:
                    print(f"用户ID: {user_info['user_id']}")
            except Exception as e:
                print(f"短信上行登录失败: {e}")
        else:
            # 短信验证码发送成功
            print(result)
            
            # 2. 测试短信验证码登录
            print("\n===== 测试短信验证码登录 =====")
            code = input("请输入收到的验证码: ")
            
            try:
                user_info = auth.login_with_sms_code(mobile, code)
                print("短信验证码登录成功！")
                print(f"用户昵称: {user_info['nickname']}")
                print(f"登录令牌: {user_info['token'][:30]}...")
                if 'uk' in user_info:
                    print(f"新的UK值: {user_info['uk']}")
                if 'user_id' in user_info:
                    print(f"用户ID: {user_info['user_id']}")
            except Exception as e:
                print(f"短信验证码登录失败: {e}")
        
    except Exception as e:
        print(f"测试失败: {e}")


if __name__ == "__main__":
    main()
